package org.flashbrighton.as3bots.models
{
	import Box2D.Collision.b2AABB;
	import Box2D.Common.Math.b2Vec2;
	import Box2D.Dynamics.b2Body;
	import Box2D.Dynamics.b2World;
	
	import flash.display.Sprite;
	import flash.events.*;
	import flash.utils.Dictionary;
	
	import org.flashbrighton.as3bots.events.DeadBotEvent;
	
	public class GameModel extends EventDispatcher
	{
		public static const TIME_STEP:Number = 1/60;
		public static const ITERATIONS:int = 10;
		
		private var _isPlaying:Boolean;
		private var _bots:Array;
		private var _botViews:Dictionary;
		private var _walls:Array;
		private var _wallViews:Dictionary;
		private var _world:b2World;
		
		
		public function GameModel()
		{
			init();
			createWorld();
		}
		
		
		private function init():void
		{
			_bots = new Array();
			_botViews = new Dictionary();
			_walls = new Array();
			_wallViews = new Dictionary();
			_isPlaying = false;
		}
		
		
		private function createWorld():void
		{
			var worldBounds:b2AABB = new b2AABB();
			worldBounds.lowerBound.Set(-20, -20); //left, top
			worldBounds.upperBound.Set(20, 20); //right, bottom
			
			_world = new b2World(worldBounds, new b2Vec2(0, 0), true);
		}
		
		
		public function get isPlaying():Boolean
		{
			return _isPlaying;
		}
		
		
		public function set isPlaying(val:Boolean):void
		{
			_isPlaying = val;
		}
		
		
		public function get botList():Array
		{
			return _bots;
		}
		
		
		public function set botList(botBodies:Array):void
		{
			_bots = botBodies;
		}
		
		
		public function get wallList():Array
		{
			return _walls;
		}
		
		
		public function get world():b2World
		{
			return _world;
		}
		
		
		public function set world(world:b2World):void
		{
			_world = world;
		}
		
		
		public function get botViews():Dictionary
		{
			return _botViews;
		}
		
		
		public function get wallViews():Dictionary
		{
			return _wallViews;
		}
		
		
		public function addBot(botBody:b2Body, view:Sprite):void
		{
			_bots.push(botBody);
			_botViews[botBody] = view;
		}
		
		
		public function removeBot(botBody:b2Body):void
		{
			_bots.splice(_bots.indexOf(botBody), 1);
			_world.DestroyBody(botBody);
			dispatchEvent(new DeadBotEvent(DeadBotEvent.DEAD, botBody));
		}
		
		
		public function addWall(wallBody:b2Body, view:Sprite):void
		{
			_walls.push(wallBody);
			_wallViews[wallBody] = view;
		}
		
		
		public function updateWorld():void
		{
			_world.Step(TIME_STEP, ITERATIONS);
			dispatchEvent(new Event(Event.CHANGE));
		}
		
	}
}